// 支持拖拽的Modal，扩展Ant Design Modal组件

import React, { Fragment, useRef, useState } from "react";
import Draggable, { DraggableProps as _DraggableProps } from 'react-draggable';
import { Modal, ModalProps } from "antd";
import { autoRc } from "@/utils/auto-render";

declare type DraggableProps = Partial<_DraggableProps>;

interface DraggableModalProps extends ModalProps {
  tip?: string;
  // 是否禁用拖拽
  disabled?: boolean;
}

const DraggableModal: React.FC<DraggableModalProps> = (props) => {
  const { children, disabled } = props;

  const ref = useRef<any>();
  const [ bounds, setBounds ] = useState<DraggableProps>({
    disabled: true,
    bounds: { left: 0, top: 0, bottom: 0, right: 0 },
  });

  const modalRender = (node: React.ReactNode): React.ReactNode => {
    if (disabled) {
      return node;
    } else {
      return <Draggable
        { ... bounds }
        onStart={ (e, data) => {
          const { clientWidth, clientHeight } = window?.document?.documentElement;
          const targetRect = ref?.current?.getBoundingClientRect();
          setBounds({
            bounds: {
              left: -targetRect?.left + data?.x,
              right: clientWidth - (targetRect?.right - data?.x),
              top: -targetRect?.top + data?.y,
              bottom: clientHeight - (targetRect?.bottom - data?.y),
            },
          });
        } }
      >
        <div ref={ ref }>{ node }</div>
      </Draggable>
    }
  };

  const renderTitle = (title?: ModalProps['title'], tip?: DraggableModalProps['tip']): any => {
    if (disabled) {
      return autoRc.renderTitle(title, tip);
    } else {
      return <div
        style={ { width: '100%', cursor: 'move' } }
        onMouseOut={ () => setBounds({ ... bounds, disabled: true }) }
        onMouseOver={ () => setBounds({ ... bounds, disabled: false }) }
      >
        <div>{ autoRc.renderTitle(title, tip) }</div>
      </div>
    }
  };

  const render = (p?: DraggableModalProps): ModalProps => disabled ? p as ModalProps : {
    ... p,
    modalRender,
    title: renderTitle(p?.title, p?.tip)
  }

  return <Fragment>
    <Modal destroyOnClose { ... render(props) }>
      { children }
    </Modal>
  </Fragment>
}

export {
  DraggableModalProps,
  DraggableModal,
}